package proyectoX.src.entidades;

import javax.swing.ImageIcon;

import proyectoX.src.aplicacion.Nivel;
import proyectoX.src.armas.BombaDevastadora;
import proyectoX.src.armas.laser;

/**
 * Abstracción correspondiente a la nave del jugador.
 *
 */
public abstract class Principal extends nave{
	//atributos
	protected int maxPuntosDeVida;
	protected int vida;
	protected BombaDevastadora bombaD;
	protected boolean invulnerabilidad;
	protected laser laser;	
	protected int municionesHabilidad;
	protected int municionesArma;

	
	/**
	 * Crea a la nave del jugador con los datos pasados por parámetro.
	 * @param velocidad Velocidad de desplazamiento. 
	 * @param ref Imagen a utilizar.
	 * @param nivel Nivel actual.
	 * @param puntosVida Puntos de vida de la nave.
	 * @param l Láser a utilizar.
	 */
	protected Principal(int velocidad, ImageIcon ref,Nivel nivel,int puntosVida,laser l) {
		super(nivel,velocidad, ref,puntosVida);
		vida=3;
		maxPuntosDeVida = puntosVida;
		bombaD= new BombaDevastadora(nivel);
		invulnerabilidad=false;
		laser=l;
	}

	//Comandos
	/**
	 * Al morir informa a nivel que debe entrar en Game Over.
	 */
	public void muerte(){	
		nivel.eliminarNavePrincipal();
	}

	/**
	 * Dependiendo de la opción el arma que se dispara. Se elige entre láser, habilidad,
	 * arma secundaria y bomba devastadora.
	 * 
	 * @param op Opción de disparo.
	 */
	public void disparar(int op) {
		switch (op){
		case 1: {
			dispararArmaPrincipal();
			break;
		}
		case 2: {
			dispararArmaSecundaria();
			break;
		}
		case 3: {
			activarHabilidadEspecial();
			break;
		}
		case 4: {
			activarBombaDevastadora();
			break;
		}
		}

	}
	
	/**
	 * Dispara el arma que destruye a todas las naves enemigas.
	 */
	private void activarBombaDevastadora() {
		bombaD.disparar(this.getLocation());
		nivel.actualizarMunicionesBombaDevastadora();
	}

	/**
	 * A ser redefinido por cada nave, activa la habilidad especial.
	 */
	protected abstract void activarHabilidadEspecial() ;

	/**
	 * A ser redefinido por cada nave, dispara el arma secundario.
	 */
	protected abstract void dispararArmaSecundaria() ;

	/**
	 * A ser redefinido por cada nave, dispara el láser que le corresponde.
	 */
	protected abstract void dispararArmaPrincipal();

	/**
	 * Cuando es chocado por una nave enemiga se le reducen los puntos de vida que poseía
	 * esa nave enemiga. 
	 * @param e Nave enemiga que la chocó.
	 */
	public void RecibirChoque(Enemiga e){
		if(!invulnerabilidad){
			reducirPuntosVida(e.getPuntosDeVida());	
			if (puntosDeVida<=0) {
				perderunaVida();
			}
			if (vida == 0) {
				muerte();
			};
		}
	}

	/**
	 * Activa la invulnerabilidad (setea el flag). 
	 * @param opcion Verdadero para activar, falso para desactivar.
	 */
	public void invulnerable(boolean opcion){
		invulnerabilidad=opcion;
	}


	/**
	 * Al perder una vida informa a nivel que debe resetear a la nave jugadora.
	 */
	private void perderunaVida(){
		vida--;
		puntosDeVida=maxPuntosDeVida;		
		nivel.inicializarPosicion();
		nivel.inicializarPuntosDeVida();
		nivel.actualizarVida();
	}

	/**
	 * Reduce a la nave jugadora la cnatidad de puntos de vida especificada por parámetro.
	 * @param danio Puntos de vida a reducir.
	 */
	private void reducirPuntosVida(int danio) {
		nivel.quitarPuntosVida(danio);
		puntosDeVida-=danio;		
	}

	/**
	 * Devuelve la cantidad de vidas que le quedan.
	 * @return Cantidad de vidas.
	 */
	public int getVida(){
		return vida;
	}

	/**
	 * Cuando recibe un disparo reduce sus puntos de vida y toma más acciones si es necesario
	 * (perder una vida, morir). Si es invulnerable no recibe daño.
	 */
	public void recibirDisparo(int dano){	
		if(!invulnerabilidad){
			reducirPuntosVida(dano);		
			if (puntosDeVida<=0) {
				perderunaVida();
			}
			if (vida == 0) {
				muerte();
			}
		}
	}
	
	/**
	 * Indica a láser que debe aumentar su nivel de poder.
	 */
	public void aumentarNivelLaser() {
		laser.aumentarNivelPoder();
	}
	
	/**
	 * Incrementa las municiones de bomba devastadora en la cantidad indicada por parámetro.
	 * @param c Cantidad a incrementar.
	 */
	public void aumentarMunicionesBomba(int c) {
		bombaD.setMuniciones(bombaD.getMuniciones()+c);
	}
	
	/**
	 * Método a redefinir para aumentar la cantidad de municiones para la habilidad especial
	 * en la cantidad indicada por parámetro.
	 * @param c Cantidad a incrementar.
	 */
	public abstract void aumentarMunicionesHabilidad(int c);
	
	/**
	 * Método a redefinir para aumentar la cantidad de municiones para el arma secnudario
	 * en la cantidad indicada por parámetro.
	 * @param c Cantidad a incrementar.
	 */
	public abstract void aumentarMunicionesArma(int c);
	
	/**
	 * Devuelve el nivel de poder del láser.
	 * @return Nivel de láser.
	 */
	public int getNivelLaser() {
		return laser.getNivelPoder();
	}
	
	/**
	 * Devuelve la cantidad de municiones de bomba devastadora que le quedan.
	 * @return Cantidad de bombas devastadoras restantes.
	 */
	public int getMunicionesBomba() {
		return bombaD.getMuniciones();
	}
	
	/**
	 * Método a redefinir que devuelve la cantidad de municiones que le quedan a la habilidad especial.
	 * @return Cantidad de munciones restantes. 
	 */
	public abstract int getMunicionesHabilidad();
	
	/**
	 * Método a redefinir que devuelve la cantidad de municiones que le quedan al arma secundario.
	 * @return Cantidad de munciones restantes. 
	 */
	public abstract int getMunicionesArma();

	/**
	 * Incrementa los puntos de vida de la nave en la cantidad indicada por parámetro
	 * si no supera al máximo posible. 
	 * @param c Cantidad a incrementar
	 * @return La cantidad de puntos de vida que realmente fueron agregados a la nave para poder informar
	 * al lugar donde lo invocaron de cuál fue la cantidad real de puntos de vida agregados.
	 */
	public int agregarPuntosDeVida(int c) {
		int resultado = c;
		
		if (puntosDeVida + c >= maxPuntosDeVida) {
			resultado = maxPuntosDeVida - puntosDeVida;
			puntosDeVida = maxPuntosDeVida;
		}
		else {
			puntosDeVida += c;
		}
		
		return resultado;
	}

	/**
	 * Aumenta en uno la cantidad de vidas de la nave.
	 */
	public void aumentarVida() {
		vida++;
	}
	
	/**
	 * Pregunta si el láser alcanzó el nivel máximo de poder.
	 * @return Verdadero si el láser está en poder máximo, falso en caso contrario.
	 */
	public boolean alcanzoLimite() {
		return laser.alcanzoNivelMaximo();
	}

}
